package server;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.nio.file.Path;
import java.util.HashMap;
import java.util.List;
import java.util.Optional;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

public class Context {

    /**
     * 所属的host
     */
    private Host host;

    /**
     * 存放url和wrapper的映射关系
     */
    private HashMap<String, Wrapper> wrapperMap = new HashMap<>();

    /**
     * context名称或者说项目名称
     */
    private String name;

    /**
     * 当前context的classpath
     */
    private Path classpath;

    /**
     * 自定义类加载器，用于加载classpath下的Servlet
     */
    private ClassLoader classLoader;

    public Context(Host host, File dir) {
        this.host = host;
        this.name = dir.getName();
        this.classpath = dir.toPath();
        this.classLoader = new MyClassLoader(classpath.toString());
    }

    public HashMap<String, Wrapper> getWrapperMap() {
        return wrapperMap;
    }

    public void setWrapperMap(HashMap<String, Wrapper> wrapperMap) {
        this.wrapperMap = wrapperMap;
    }

    public String getName() {

        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Path getClasspath() {
        return classpath;
    }

    public void setClasspath(Path classpath) {
        this.classpath = classpath;
    }

    public void loadServlet() {
        String configPath = getConfigPath();

        try {
            InputStream resourceAsStream = new FileInputStream(configPath);
            SAXReader saxReader = new SAXReader();
            Document document = saxReader.read(resourceAsStream);
            Element rootElement = document.getRootElement();
            List<Element> selectNodes = rootElement.selectNodes("//servlet");
            for (int i = 0; i < selectNodes.size(); i++) {
                Element element =  selectNodes.get(i);
                // <servlet-name>lagou</servlet-name>
                Element servletnameElement = (Element) element.selectSingleNode("servlet-name");
                String servletName = servletnameElement.getStringValue();
                // <servlet-class>server.LagouServlet</servlet-class>
                Element servletclassElement = (Element) element.selectSingleNode("servlet-class");
                String servletClass = servletclassElement.getStringValue();


                // 根据servlet-name的值找到url-pattern
                Element servletMapping = (Element) rootElement.selectSingleNode("/web-app/servlet-mapping[servlet-name='" + servletName + "']");
                String urlPattern = servletMapping.selectSingleNode("url-pattern").getStringValue();
                Wrapper wrapper = new Wrapper(urlPattern, (HttpServlet) classLoader.loadClass(servletClass).newInstance(), this);
                this.wrapperMap.put(urlPattern, wrapper);
            }



        } catch (DocumentException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }

    }

    private String getConfigPath() {
        return this.classpath.toString().concat("\\WEB-INF\\web.xml");
    }

    public Servlet getServlet(String url) {
        Wrapper wrapper = wrapperMap.get(getUrlPatern(url));
        return Optional.ofNullable(wrapper).map(w -> w.getServlet()).orElse(null);
    }

    private String getUrlPatern(String url) {
        return url.substring(url.indexOf(name) + name.length(), url.length());
    }
}
